/*
 * ============================================================================
 * GNU Lesser General Public License
 * ============================================================================
 *
 * Servoy - Smart Technology For Smart Clients.
 * Copyright � 1997-2009 Servoy BV http://www.servoy.com
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
 * 
 * Servoy B.V.
 * De Brand 26
 * 3823 LJ Amersfoort
 * The Netherlands 
 * http://www.servoy.com
 */
package com.servoy.r3.plugins;

import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;

import javax.print.PrintService;

import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperPrintManager;
import net.sf.jasperreports.view.JasperViewer;

import com.servoy.j2db.dataprocessing.JSDataSet;
import com.servoy.j2db.scripting.IScriptObject;
import com.servoy.j2db.util.Debug;
import com.servoy.j2db.util.Utils;

/**
 * IScriptObject impl.
 * For external library dependancies, see:
 * http://www.jasperforge.org/jaspersoft/opensource/business_intelligence/jasperreports/requirements.html
 */
public class JasperReportsProvider implements IScriptObject {
    private JasperReportsPlugin plugin;

    private IJasperReportsService jasperReportService = null;

    private static final int PARAMETER = 1;

    private static final int TOOLTIP = 2;

    private static final int EXAMPLE = 3;

    private static final String PROPERTIES[][][] = {
	    // methodname, parameters, tooltip, example
	    {
		{ "runReport" },
		{ "serverName", "reportFileName ", "exportFileName / boolean showPrintDialog / printerName", "outputFormat", "Object parameters", "[locale]" },
		{ "Execute a Report" }, {} },
	    { { "writeFileToReportsDir" }, { "reportFileName", "JSFile reportFile" }, { "Store a reportFile on the Server" },
		    { "// .jasper or .jrxml files can be used\n" + 
	    	"var file = plugins.file.readFile('e:\\\\temp\\\\sample.jasper');\n" + 
	    	"plugins.jasperPluginRMI.writeFileToReportsDir('myCustomerReport.jasper', file);\n" + 
	    	"// Writes to a subfolder from the reports directory. All the folders from the path must exist.\n" +
	    	"plugins.jasperPluginRMI.writeFileToReportsDir('\\\\subdir\\\\myCustomerReport.jasper', file);\n"} },
	    { { "readFileFromReportsDir" }, { "reportFileName" }, { "Retrieve a reportFile from the Server" },
		    { "var reportFileArray = plugins.jasperPluginRMI.readFileFromReportsDir('myCustomerReport.jasper');\n" + 
	    	"// Subfolders can be used to read files.\n" + 
	    	"var reportFileArray = plugins.jasperPluginRMI.readFileFromReportsDir('\\\\subdir\\\\myCustomerReport.jasper');"} },
	    { { "compileReport" }, { "reportFileName", "[destinationFileName]"}, { "Compile a Jasper Reports .jrxml file to a .jasper file." },
		    { "// Compile the .jrxml jasper report file to a .jasper file. The name of the compiled file is given by the report name.\n" +
	    		"// The report name as an absolute path. Results the compiled c:\\temp\\samplereport.jasper file.\n" +
	    		"var success = plugins.jasperPluginRMI.compileReport('c:\\\\temp\\\\samplereport.jrxml');\n" +
	    		"// The report name as a relative path. The file will be searched relative to the ReportDirectory.\n" +
		    	"var success = plugins.jasperPluginRMI.compileReport('myCustomerReport1.jrxml');\n" +
	    		"var success = plugins.jasperPluginRMI.compileReport('\\\\subdir\\\\myCustomerReport2.jrxml');\n" +
	    		"// To specify a different destination file than the original filaname, the second parameter can be incouded.\n" +
	    		"// If it is relative, the file will be created relative to the ReportDirectory.\n" + 
	    		"var success = plugins.jasperPluginRMI.compileReport('c:\\\\temp\\\\samplereport.jrxml', 'd:\\\\temp2\\\\destreport.jasper');"} },
		{ { "getReports"}, {"filter"}, {"Retrieve a String array of available reports, based on the reports directory."},
		    {"// COMPILED - only compiled reports, NONCOMPILED - only non-compiled reports\n// No parameter or any string return all the reports\nvar result = plugins.jasperPluginRMI.getReports('NONCOMPILED');\napplication.output(result[0]);"}},
		{ { "getReportParameters"}, {"report"}, {"Retrieve a JSDataSet with the parameters except the system defined ones."},
		    {"var ds = plugins.jasperPluginRMI.getReportParameters('sample.jrxml');\nvar csv = ds.getAsText(',','\\n','\"',true);\napplication.output(csv);"}},
		{ { "reportDirectory" }, { }, { "Property for retrieving the reports directory from the server." },
		    	{ "// By defaul the value is read from the adim page Server Plugins, the directory.jasper.report property.\n// If the client modifies the reportDirectory property, this value will be used instead of the default one for the whole client session and only for this client. Each client session has it's own reportDirectory value." }}
    };

    JasperReportsProvider(JasperReportsPlugin p) throws Exception{
		plugin = p;
	}

    public String[] getProperty(String methodName, int prop) {
	for (int i = 0; i < PROPERTIES.length; i++) {
	    String as[][] = PROPERTIES[i];
	    if (as[0][0].equals(methodName)) {
		return as[prop];
	    }
	}
	return null;
    }

    public boolean isDeprecated(String methodName) {
	if (methodName == null)
	    return false;
	else if ("".equals(methodName)) {
	    return true;
	}
	else if ("jasperReport".equals(methodName)) {
		return true;
	}
	else if ("jasperCompile".equals(methodName)) {
		return true;
	}
	else if ("writeFile".equals(methodName)) {
		return true;
	}
	else if ("readFile".equals(methodName)) {
		return true;
	}
	
	return false;
    }

    public String[] getParameterNames(String methodName) {
	return getProperty(methodName, PARAMETER);
    }

    public String getSample(String methodName) {
	if (methodName == null)
	    return null;
	else if ("runReport".equals(methodName)) {
	    StringBuffer retval = new StringBuffer();
	    retval.append("// The method runs a client report specified by the second parameter acording to the output format. The report can be a compiled jasper file or a jrxml file from a relative path to the reportDirectory or an absolute one.\n\n");
	    retval.append("/* To view the result of the customers report in the Jasper Report viewer in the SmartClient or as PDF in the WebClient\n");
	    retval.append(" * Note: the parameters argument is used to send additional parameters into the report. For example:\n");
	    retval.append(" * {pcustomerid: forms.customers.customer_id} to send just 1 parameter called pcustomerid, which contains the value of dataprovider customer_id in the selected record on the customers form\n");
	    retval.append(" * The parameters argument is an Object, which can be instantiated in two ways:\n");
	    retval.append(" * var o = new Object();\n");
	    retval.append(" * o.pcustomerid = forms.customers.customer_id;\n");
	    retval.append(" * or:\n");
	    retval.append(" * var o = {pcustomerid: forms.customers.customer_id};\n");
	    retval.append(" */\n");
	    retval.append("application.updateUI(); //to make sure the Servoy window doesn't grab focus after showing the Jasper Viewer\n");
	    retval.append("plugins.jasperPluginRMI.runReport(forms.customers.controller.getServerName(),'myCustomerReport.jasper',null,'view',{pcustomerid: forms.customers.customer_id});\n");
	    retval.append("\n");
	    retval.append("/* To request a report in a different Language than the current language of the client, it's possible to specify a Locale string as the locale argument. For example: 'en' or 'es' or 'nl'\n");
	    retval.append(" * When the locale argument is not specified, the report will be in the current langauge of the Client\n");
	    retval.append(" * i18n keys of Servoy can be used inside Jasper Reports using the $R{i18n-key} notation\n");
	    retval.append(" */\n");
	    retval.append("//plugins.jasperPluginRMI.runReport(forms.customers.controller.getServerName(),'myCustomerReport.jasper',null,'view',{pcustomerid: forms.customers.customer_id},'nl');\n");
	    retval.append("\n");
	    retval.append("/* To print the result of the customers report in the SmartClient,\n");
	    retval.append(" * the third parameter can contain the name of the printer to which the report needs to be printed\n");
	    retval.append(" * or can contain true (boolean value) to show a printdialog before printing\n");
	    retval.append(" * if null is specified, it will print without showing the print dialog to the default printer\n");
	    retval.append(" * Note: In the WebClient a PDF will be pushed to the Client when the outputType is specified as 'print'\n");
	    retval.append(" */\n");
	    retval.append("//plugins.jasperPluginRMI.runReport(forms.customers.controller.getServerName(),'myCustomerReport.jasper',null,'print',{pcustomerid: forms.customers.customer_id});\n");
	    retval.append("\n");
	    retval.append("/* To generate the report in the specified output format and save the result to 'myReport.html' in the root of the c-drive:\n");
	    retval.append(" * Supported output formats are: html, pdf, excel( or xls), xls_1_sheet (1 page per sheet), rtf, txt, csv, odt, jrprint and xml\n");
	    retval.append(" * Note: in the WebClient, the file will be saved serverside, so the specified path needs to be valid serverside\n");
	    retval.append(" */\n");
	    retval.append("//plugins.jasperPluginRMI.runReport(forms.customers.controller.getServerName(),'myCustomerReport.jasper','c:/myReport.html','html',{pcustomerid: forms.customers.customer_id});\n");
	    retval.append("//plugins.jasperPluginRMI.runReport(forms.customers.controller.getServerName(),'myCustomerReport.jasper','c:/myReport.pdf','pdf',{pcustomerid: forms.customers.customer_id});\n");
	    retval.append("//plugins.jasperPluginRMI.runReport(forms.customers.controller.getServerName(),'myCustomerReport.jasper','c:/myReport.rtf','rtf',{pcustomerid: forms.customers.customer_id});\n");
	    retval.append("//plugins.jasperPluginRMI.runReport(forms.customers.controller.getServerName(),'myCustomerReport.jasper','c:/myReport.jrprint','jrprint',{pcustomerid: forms.customers.customer_id});\n");
	    retval.append("//plugins.jasperPluginRMI.runReport(forms.customers.controller.getServerName(),'myCustomerReport.jasper','c:/myReport.txt','txt',{pcustomerid: forms.customers.customer_id});\n");
	    retval.append("//plugins.jasperPluginRMI.runReport(forms.customers.controller.getServerName(),'myCustomerReport.jasper','c:/myReport.csv','csv',{pcustomerid: forms.customers.customer_id});\n");
	    retval.append("//plugins.jasperPluginRMI.runReport(forms.customers.controller.getServerName(),'myCustomerReport.jasper','c:/myReport.odt','odt',{pcustomerid: forms.customers.customer_id});\n");
	    retval.append("//plugins.jasperPluginRMI.runReport(forms.customers.controller.getServerName(),'myCustomerReport.jasper','c:/myReport.xls','xls' /*or excel*/,{pcustomerid: forms.customers.customer_id});\n");
	    retval.append("//plugins.jasperPluginRMI.runReport(forms.customers.controller.getServerName(),'myCustomerReport.jasper','c:/myReport.xls','xls_1_sheet',{pcustomerid: forms.customers.customer_id});\n");
	    retval.append("//plugins.jasperPluginRMI.runReport(forms.customers.controller.getServerName(),'myCustomerReport.jasper','c:/myReport.xml','xml',{pcustomerid: forms.customers.customer_id});\n");
	    retval.append("\n");
	    retval.append("/* Jasper Reports supports queries with IN operators through the following notation: X${IN,columnName,parameterName} like 'select * from customers where X$(IN,customer_id,pcustomeridlist)\n");
	    retval.append(" * When using this notation, the pcustomeridlist parameter needs to contain one or more values in the following way:\n");
	    retval.append(" */\n");
	    retval.append("//var idlist = new Array()\n");
	    retval.append("//idlist[0] = 1\n");
	    retval.append("//idlist[1] = 26\n");
	    retval.append("//plugins.jasperPluginRMI.jasperReport(forms.customers.controller.getServerName(),'myCustomerReport.jasper',null,'view',{pcustomeridlist: idlist});\n");
	    retval.append("\n//The return value is a byte array with the content of the file generated that can be further used.");
	    retval.append("//var res = plugins.jasperPluginRMI.runReport(currentcontroller.getServerName(),'samplereport.jrxml', null, 'pdf', null);");
	    retval.append("//plugins.file.writeFile('e:\\\\sample.pdf', res);");
	    return retval.toString();
	} else {
	    String[] as = getProperty(methodName, EXAMPLE);
	    if (as != null)
		return as[0];
	}
	return null;
    }

    public String getToolTip(String methodName) {
	String[] as = getProperty(methodName, TOOLTIP);
	if (as != null)
	    return as[0];
	return null;
    }

    public Class[] getAllReturnedTypes() {
	return null;
    }

    /**
     * Fix for bug ID 6255588 from Sun bug database
     * @param job print job that the fix applies to
     */
    public static void initPrinterJobFields(PrinterJob job) {
	Class clazz = job.getClass();
	try {
	    Class printServiceClass = Class.forName("javax.print.PrintService");
	    Method method = clazz.getMethod("getPrintService", (Class[]) null);
	    Object printService = method.invoke(job, (Object[]) null);
	    method = clazz.getMethod("setPrintService", new Class[] { printServiceClass });
	    method.invoke(job, new Object[] { printService });
	} catch (NoSuchMethodException e) {
	} catch (IllegalAccessException e) {
	} catch (InvocationTargetException e) {
	} catch (ClassNotFoundException e) {
	}
    }

    public boolean setPrintService(PrinterJob printJob, String printer) throws Exception {
	PrintService[] service = PrinterJob.lookupPrintServices();
	// enable if on list otherwise error
	boolean match = false;
	int count = service.length;
	try {
	    for (int i = 0; i < count; i++) {
		if (service[i].getName().indexOf(printer) != -1) {
		    printJob.setPrintService(service[i]);
		    i = count;
		    match = true;
		}
	    }
	} catch (PrinterException e) {
	    Debug.error(e);
	    throw new Exception(e.getMessage());
	}
	return match;
    }

	/**
	 *	@deprecated
	 *	@see	js_runReport(String dbalias, String report, Object arg, String type, Object parameters)
	 */
    public byte[] js_jasperReport(String dbalias, String report, Object arg, String type, Object parameters) throws Exception {
    	return js_runReport(dbalias, report, arg, type, parameters, null);
    }
    
	/**
	 *	@deprecated
	 *	@see	js_runReport(String dbalias, String report, Object arg, String type, Object parameters, String localeString)
	 */
    public byte[] js_jasperReport(String dbalias, String report, Object arg, String type, Object parameters, String localeString) throws Exception {
    	return js_runReport(dbalias, report, arg, type, parameters, localeString);
    }
    
    public byte[] js_runReport(String dbalias, String report, Object arg, String type, Object parameters) throws Exception {
	return js_runReport(dbalias, report, arg, type, parameters, null);
    }

    public byte[] js_runReport(String dbalias, String report, Object arg, String type, Object parameters, String localeString) throws Exception {

	Map params = (Map) new JSArgumentsUnwrap().unwrapJSObject(parameters);
	if (params == null)
	    params = new HashMap();

	boolean showPrintDialog = false;
	String file = "";
	boolean nooutput = false;
	if (arg instanceof String) {
	    file = arg.toString();
	} else if (arg instanceof Boolean) {
	    showPrintDialog = Utils.getAsBoolean(arg);
	} else {
		if (arg != null)
			file = arg.toString(); //To support passing in a JSFile object
		else nooutput = true;
	}

	Debug.trace("JasperTrace: JasperReport initialize");
	// create if not yet created
	if (jasperReportService == null) {
	    try {
		jasperReportService = (IJasperReportsService) plugin.getIClientPluginAccess().getServerService("servoy.IJasperReportService");
	    } catch (Exception e) {
		Debug.error(e);
		throw new Exception("Jasper Exception: Cannot connect to service-server");
	    }
	}

	// in case the server is not started in developer
	if (jasperReportService != null) {
	    try {
		Debug.trace("JasperTrace: JasperReport service found");

		if (parameters != null) {
		    for (Iterator iter = params.keySet().iterator(); iter.hasNext();) {
			Object key = iter.next();
			Object value = params.get(key);
			if (value instanceof ByteArrayInputStream) {
			    byte[] buf = null;
			    ByteArrayInputStream is = (ByteArrayInputStream) value;
			    is.read(buf);
			}
		    }
		}

		/*
		 * This plugin is backwards compatible up to Servoy 2.2 Only
		 * since 3.5.1, the application.getReleaseNumber() API was added
		 * to determine properly which version you are running To be
		 * compatible back to Servoy 2.2, the code below is to test
		 * which functions are available in the Servoy Instance. This
		 * code needs to be compiled against Servoy 3.5.3 or higher,
		 * since Servoy 3.5.3 implements the i18n getResourceBundle API
		 */
		int applicationType = -1;
		boolean supportsWebClientAPI = false;
		boolean supportsResourcebundleAPI = false;

		try {
		    applicationType = plugin.getIClientPluginAccess().getApplicationType(); /** Support added in 3.0, together with WebClient*/
		} catch (Exception e1) {/* Ignore */
		}

		try {
		    Class.forName("com.servoy.j2db.server.headlessclient.IWebClientPluginAccess"); /** Supported as of 3.5 RC 7*/
		    supportsWebClientAPI = true;
		} catch (ClassNotFoundException e) {/* Ignore */
		}

		try {
		    if (plugin.getIClientPluginAccess().getReleaseNumber() >= 516) {/** Proper ResourceBundle support added in 3.5.3*/
			supportsResourcebundleAPI = true;
		    }
		    supportsWebClientAPI = true;
		} catch (NoSuchMethodError e2) {/* Ignore */
		}

		if (supportsResourcebundleAPI) {
		    new JasperReportsI18NHandler().appendI18N(params, applicationType == 5 /** Hardcoded integer: IClientPluginAccess.WEB_CLIENT not supported in 3.0*/, plugin.getIClientPluginAccess(), localeString);
		}

		byte[] jsp = null;
		// Report Viewer requested, or Report print in WC requested
		if (type.toLowerCase().startsWith("view") || (type.toLowerCase().startsWith("print") && applicationType == 5)) {
		    if (applicationType == 5 /** Hardcoded integer: IClientPluginAccess.WEB_CLIENT not supported in 3.0*/) {
			if (supportsWebClientAPI) {
			    jsp = jasperReportService.jasperReport(dbalias, report, "pdf", params, plugin.getJasperReportsDirectory());
			    new JasperReportsWebViewer().show(plugin.getIClientPluginAccess(), jsp, file);
			} else {
			    Debug.log("JasperLog: ReportViewer requested in WebClient (not supported < Servoy 3.5.1)");
			}
		    } else {
			JasperPrint jp = jasperReportService.jasperViewer(dbalias, report, params, plugin.getJasperReportsDirectory());
			
			JasperViewer jasperviewer;
			
			if (localeString != null)
				jasperviewer = new JasperViewer(jp, false, new Locale(localeString));
			else
				jasperviewer = new JasperViewer(jp, false);
			
			if (jp != null && jp.getPages() != null && jp.getPages().size() > 0) {
			    jasperviewer.setVisible(true);
			    jasperviewer.setDefaultCloseOperation(JasperViewer.DISPOSE_ON_CLOSE);
                        } else {
                            jasperviewer.dispose();
                        }
		    }
		}
		// Printing only supported in SC. Printing in WC handled
		// previously though PDF push
		else if (type.toLowerCase().startsWith("print")) {

		    // Fill the report and get the JasperPrint instance
		    JasperPrint jp = jasperReportService.jasperViewer(dbalias, report, params, plugin.getJasperReportsDirectory());

		    // Shows print dialog before printing
		    if (showPrintDialog || file == null || file == "true") {
			JasperPrintManager.printReport(jp, true);
		    }
		    // Skips print dialog
		    else if (file.equalsIgnoreCase("false") || file.equalsIgnoreCase("default")) {
			JasperPrintManager.printReport(jp, false);
		    }
		    // Assumes parameter file contains a printerName
		    else {
			Debug.trace("JasperTrace: printer: " + file);
			PrinterJob printJob = PrinterJob.getPrinterJob();
			// fix for bug ID 6255588 from Sun bug database
			initPrinterJobFields(printJob);
			/*
			 * or onother workaround try {
			 * printerJob.setPrintService(printerJob.getPrintService()); }
			 * catch (PrinterException e) {}
			 */

			if (setPrintService(printJob, file)) {
			    JasperReportsPrinter.printPages(jp, printJob);
			} else {
			    Debug.trace("JasperTrace: unable to specify printer: " + file);
			}
		    }
		} else {
		    jsp = jasperReportService.jasperReport(dbalias, report, type, params, plugin.getJasperReportsDirectory());
		    
		    if (nooutput == false)
		    {
		    	jasperReportService.saveByteArrayToFile(file, jsp, plugin.getJasperReportsDirectory());
		    }
		}
		Debug.trace("JasperTrace: JasperReport finished");
		return jsp;
	    } catch (Exception e) {
		Debug.error(e);
		throw new Exception(e.getMessage());
	    }
	}
	Debug.error("JasperTrace: Jasper Exception: No service running");
	throw new Exception("JasperTrace: Jasper Exception: No service running");
    }

    public boolean js_compileReport(String report) throws Exception {
    	return js_compileReport(report, null);
    }
    
    public boolean js_compileReport(String report, String destination) throws Exception {

	Debug.trace("JasperTrace: JasperCompile initialize");
	boolean compiled = false;

	connectJasperService();

	try {
	    Debug.trace("JasperTrace: JasperCompile starting");
	    compiled = jasperReportService.jasperCompile(report, destination, plugin.getJasperReportsDirectory());
	    Debug.trace("JasperTrace: JasperCompile finished");
	} catch (Exception e) {
	    Debug.error(e);
	    throw new Exception(e.getMessage());
	}

	return compiled;
    }
    
    
	/**
	 *	@deprecated
	 *	@see	js_compileReport(String report)
	 */
    public boolean js_jasperCompile(String report) throws Exception {
    	return js_compileReport(report);
    }
    
	/**
	 *	@param forceRecompile 
	 * 	@deprecated
	 *	@see	js_compileReport(String report)
	 */
    public boolean js_jasperCompile(String report, boolean forceRecompile) throws Exception {
    	return js_compileReport(report);
    }
    
	/**
	 *	@deprecated
	 *	@see	js_writeFileToReportsDir(String filenm, Object obj)
	 */ 
    public boolean js_writeFile(String filenm, Object obj) throws Exception {
    	return js_writeFileToReportsDir(filenm, obj);
    }
    
    public boolean js_writeFileToReportsDir(String filenm, Object obj) throws Exception {

	connectJasperService();

	try {
	    Debug.trace("JasperTrace: JasperWriteFile starting");
	    boolean b = jasperReportService.writeFile(filenm, obj, plugin.getJasperReportsDirectory());
	    Debug.trace("JasperTrace: JasperWriteFile finished");
	    return b;
	} catch (Exception e) {
	    Debug.error(e);
	    return false;
	}
    }

	/**
	 *	@deprecated
	 *	@see	js_readFileFromReportsDir(String filenm)
	 */    
    public byte[] js_readFile(String filenm) throws Exception {
    	return js_readFileFromReportsDir(filenm);
    }
    
    public byte[] js_readFileFromReportsDir(String filenm) throws Exception {

	byte[] b = null;

	connectJasperService();

	try {
	    Debug.trace("JasperTrace: JasperReadFile starting");
	    b = jasperReportService.readFile(filenm, plugin.getJasperReportsDirectory());
	    Debug.trace("JasperTrace: JasperReadFile finished");
	} catch (Exception e) {
	    Debug.error(e);
	    throw new Exception(e.getMessage());
	}
	return b;
    }

    public String js_getReportDirectory() throws Exception {	
    	return plugin.getJasperReportsDirectory();
    }

    public void js_setReportDirectory(String jasperDirectorie) throws Exception {
    	plugin.setJasperReportsDirectory(jasperDirectorie);
    }

    public void connectJasperService() throws Exception {

	Debug.trace("JasperTrace: service connection initialize");
	// create if not yet created
	if (jasperReportService == null) {
	    try {
		jasperReportService = (IJasperReportsService) plugin.getIClientPluginAccess().getServerService("servoy.IJasperReportService");
	    } catch (Exception ex) {
		Debug.error(ex);
		throw new Exception("JasperTrace: Jasper Exception: Cannot connect to service-server");
	    }
	}

	// in case the server is not started in developer
	if (jasperReportService == null) {
	    System.err.println("JasperTrace: Jasper Exception: No service running");
	    throw new Exception("JasperTrace: Jasper Exception: No service running");
	}
	Debug.trace("JasperTrace: service connection found");
    }
 
    public String[] js_getReports() throws Exception {
		return getReports(true, true);
	}

	public String[] js_getReports(String filter) throws Exception {

		if (filter.toUpperCase().compareTo("COMPILED") == 0) {
			return getReports(true, false);
		} else if (filter.toUpperCase().compareTo("NONCOMPILED") == 0) {
			return getReports(false, true);
		}

		return getReports(true, true);
	}

	private String[] getReports(boolean compiled, boolean uncompiled)
			throws Exception {

		String[] reports = null;

		connectJasperService();

		try {
			Debug.trace("JasperTrace: getReports starting");
			reports = jasperReportService.getReports(compiled, uncompiled);
			Debug.trace("JasperTrace: getReports finished");
		} catch (Exception e) {
			Debug.error(e);
			throw new Exception(e.getMessage());
		}

		return reports;
	}
	
	public JSDataSet js_getReportParameters(String report) throws Exception {
		
		JSDataSet ds = null;
		
		connectJasperService();

		try {
			Debug.trace("JasperTrace: getReportParameters starting");
			ds = jasperReportService.getReportParameters(report, plugin.getJasperReportsDirectory());
			Debug.trace("JasperTrace: getReportParameters finished");
		} catch (Exception e) {
			Debug.error(e);
			throw new Exception(e.getMessage());
		}
		
		return ds;
	}
	
	public String js_getPluginVersion(){
		return "2.1.6_beta";
		
		/*
		 * Added destination optional parameter for compileReport method
		 * Renamed jasperReport -> runReport, jasperCompile -> compileReport, readFile -> readFileFromReportsDir, writeFile -> writeFileToReportsDir methods and deprecated the old ones.
		 * Updated methods comments to reflect changes and functionality.
		 * Changed jasperReport to accept null output for using only the array return value.
		 * 
		 */
	}
	/**
	 * @param ver  
	 */
	public void js_setPluginVersion(String ver){
		// DO NOTHING. READ ONLY PROPERTY.
	}
}
